/**
 * 有意识停留jquery插件
 * 鼠标移入时计算当前进入象限然后悬浮块由此象限滑入
 */
;
(function($, undefined) {
    /*
     * HoverDir object.
     */
    $.HoverDir = function(options, element) {
        this.$el = $(element);
        this._init(options);
    };
    $.HoverDir.defaults = {
        hoverDelay: 0,
        reverse: false,
        hoverElem: "div"
    };
    $.HoverDir.prototype = {
        _init: function(options) {
            this.options = $.extend(true, {}, $.HoverDir.defaults, options);
            // load the events
            this._loadEvents();
        },
        _loadEvents: function() {
            var _self = this;
            this.$el.on('mouseenter.hoverdir, mouseleave.hoverdir', function(event) {
                var $el = $(this),
                    evType = event.type,
                    $hoverElem = $el.find(_self.options.hoverElem),
                    direction = _self._getDir($el, {
                        x: event.pageX,
                        y: event.pageY
                    }),
                    hoverClasses = _self._getClasses(direction);
                $hoverElem.removeClass();
                if (evType === 'mouseenter') {
                    $hoverElem.hide().addClass(hoverClasses.from);
                    clearTimeout(_self.tmhover);
                    _self.tmhover = setTimeout(function() {
                        $hoverElem.show(0, function() {
                            $(this).addClass('da-animate').addClass(hoverClasses.to);
                        });
                    }, _self.options.hoverDelay);
                } else {
                    $hoverElem.addClass('da-animate');
                    clearTimeout(_self.tmhover);
                    $hoverElem.addClass(hoverClasses.from);
                }
            });
        },
        // credits : http://stackoverflow.com/a/3647634
        _getDir: function($el, coordinates) {
            /** the width and height of the current div **/
            var w = $el.width(),
                h = $el.height(),
                /** calculate the x and y to get an angle to the center of the div from that x and y. **/
                /** gets the x value relative to the center of the DIV and "normalize" it **/
                x = (coordinates.x - $el.offset().left - (w / 2)) * (w > h ? (h / w) : 1),
                y = (coordinates.y - $el.offset().top - (h / 2)) * (h > w ? (w / h) : 1),
                /** the angle and the direction from where the mouse came in/went out clockwise (TRBL=0123);**/
                /** first calculate the angle of the point, 
                add 180 deg to get rid of the negative values
                divide by 90 to get the quadrant
                add 3 and do a modulo by 4  to shift the quadrants to a proper clockwise TRBL (top/right/bottom/left) **/
                direction = Math.round((((Math.atan2(y, x) * (180 / Math.PI)) + 180) / 90) + 3) % 4;
            return direction;
        },
        _getClasses: function(direction) {
            var fromClass, toClass;
            switch (direction) {
                case 0:
                    // from top
                    (!this.options.reverse) ? fromClass = 'da-slideFromTop': fromClass = 'da-slideFromBottom';
                    toClass = 'da-slideTop';
                    break;
                case 1:
                    // from right
                    (!this.options.reverse) ? fromClass = 'da-slideFromRight': fromClass = 'da-slideFromLeft';
                    toClass = 'da-slideLeft';
                    break;
                case 2:
                    // from bottom
                    (!this.options.reverse) ? fromClass = 'da-slideFromBottom': fromClass = 'da-slideFromTop';
                    toClass = 'da-slideTop';
                    break;
                case 3:
                    // from left
                    (!this.options.reverse) ? fromClass = 'da-slideFromLeft': fromClass = 'da-slideFromRight';
                    toClass = 'da-slideLeft';
                    break;
            };
            return {
                from: fromClass,
                to: toClass
            };
        }
    };
    var logError = function(message) {
        if (this.console) {
            console.error(message);
        }
    };
    $.fn.hoverdir = function(options) {
        if (typeof options === 'string') {
            var args = Array.prototype.slice.call(arguments, 1);
            this.each(function() {
                var instance = $.data(this, 'hoverdir');
                if (!instance) {
                    logError("cannot call methods on hoverdir prior to initialization; " +
                        "attempted to call method '" + options + "'");
                    return;
                }
                if (!$.isFunction(instance[options]) || options.charAt(0) === "_") {
                    logError("no such method '" + options + "' for hoverdir instance");
                    return;
                }
                instance[options].apply(instance, args);
            });
        } else {
            this.each(function() {
                var instance = $.data(this, 'hoverdir');
                if (!instance) {
                    $.data(this, 'hoverdir', new $.HoverDir(options, this));
                }
            });
        }
        return this;
    };
})(jQuery);
